package com.java110.mall.goods.cmd.product;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.annotation.Java110Transactional;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.dto.file.FileRelDto;
import com.java110.dto.housekeeping.HousekeepingServDto;
import com.java110.dto.housekeeping.HousekeepingTypeDto;
import com.java110.dto.inoutOrder.InoutOrderDto;
import com.java110.dto.shop.ShopDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.cart.IInoutOrderInnerServiceSMO;
import com.java110.intf.cart.IInoutOrderProductInnerServiceSMO;
import com.java110.intf.goods.*;
import com.java110.intf.shop.IShopHouseInnerServiceSMO;
import com.java110.intf.shop.IShopInnerServiceSMO;
import com.java110.intf.system.IFileInnerServiceSMO;
import com.java110.intf.system.IFileRelInnerServiceSMO;
import com.java110.intf.user.IUserV1InnerServiceSMO;
import com.java110.po.file.FileRelPo;
import com.java110.po.inoutOrder.InoutOrderPo;
import com.java110.po.inoutOrder.InoutOrderProductPo;
import com.java110.po.product.ProductPo;
import com.java110.po.product.ProductDetailPo;
import com.java110.po.product.ProductH5MenuPo;
import com.java110.po.product.ProductServKeywordPo;
import com.java110.po.product.ProductSpecValuePo;
import com.java110.po.shop.ShopDistributionModePo;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.BeanConvertUtil;
import com.java110.utils.util.ListUtil;
import com.java110.utils.util.StringUtil;
import com.java110.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 添加商品
 */
@Java110Cmd(serviceCode = "product.saveProduct")
public class SaveProductCmd extends Cmd {

    @Autowired
    private IProductInnerServiceSMO productInnerServiceSMOImpl;

    @Autowired
    private IFileInnerServiceSMO fileInnerServiceSMOImpl;

    @Autowired
    private IFileRelInnerServiceSMO fileRelInnerServiceSMOImpl;

    @Autowired
    private IProductSpecValueInnerServiceSMO productSpecValueInnerServiceSMOImpl;

    @Autowired
    private IProductDetailInnerServiceSMO productDetailInnerServiceSMOImpl;

    @Autowired
    private IProductServKeywordInnerServiceSMO productServKeywordInnerServiceSMOImpl;

    @Autowired
    private IInoutOrderProductInnerServiceSMO iInoutOrderProductInnerServiceSMOImpl;

    @Autowired
    private IInoutOrderInnerServiceSMO inoutOrderInnerServiceSMOImpl;

    @Autowired
    private IUserV1InnerServiceSMO userInnerServiceSMOImpl;

    @Autowired
    private IProductCategoryInnerServiceSMO productCategoryInnerServiceSMOImpl;

    @Autowired
    private IShopHouseInnerServiceSMO shopHouseInnerServiceSMOImpl;

    @Autowired
    private IProductSpecInnerServiceSMO productSpecValuePosImpl;
    @Autowired
    private IShopDistributionModeInnerServiceSMO shopDistributionModeInnerServiceSMOImpl;

    @Autowired
    private IHousekeepingTypeInnerServiceSMO housekeepingTypeInnerServiceSMOImpl;

    @Autowired
    private IProductH5MenuV1InnerServiceSMO productH5MenuV1InnerServiceSMOImpl;

    @Autowired
    private IShopInnerServiceSMO shopInnerServiceSMOImpl;


    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {

        Assert.hasKeyAndValue(reqJson, "prodName", "请求报文中未包含prodName");
        Assert.hasKeyAndValue(reqJson, "keyword", "请求报文中未包含keyword");
        Assert.hasKeyAndValue(reqJson, "categoryId", "请求报文中未包含categoryId");
        Assert.hasKeyAndValue(reqJson, "unitName", "请求报文中未包含unitName");
        Assert.hasKeyAndValue(reqJson, "sort", "请求报文中未包含sort");
        Assert.hasKeyAndValue(reqJson, "isPostage", "请求报文中未包含isPostage");
        Assert.hasKeyAndValue(reqJson, "coverPhoto", "请求报文中未包含商品封面");
        Assert.hasKeyAndValue(reqJson, "content", "请求报文中未包含商品描述");

        Assert.hasKey(reqJson, "carouselFigurePhoto", "请求报文中未包含轮播图");
        Assert.hasKey(reqJson, "productSpecs", "请求报文中未包含规格信息");

        ShopDto shopDto = new ShopDto();
        shopDto.setShopId(reqJson.getString("shopId"));
        shopDto.setState(ShopDto.STATE_Y);//审核通过的店铺
        List<ShopDto> shopDtos = shopInnerServiceSMOImpl.queryShops(shopDto);
        if (ListUtil.isNull(shopDtos)) {
           throw new CmdException("审核通过店铺才可以添加");
        }
    }

    @Override
    @Java110Transactional
    public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {

        String storeId = cmdDataFlowContext.getReqHeaders().get("store-id");
        String userId = cmdDataFlowContext.getReqHeaders().get("user-id");

        String coverPhoto = reqJson.getString("coverPhoto");
        JSONArray carouselFigurePhoto = reqJson.getJSONArray("carouselFigurePhoto");

        JSONArray productSpecs = reqJson.getJSONArray("productSpecs");

        if (ListUtil.isNull(carouselFigurePhoto)) {
            throw new IllegalArgumentException("请求报文中未包含轮播图");
        }
        if (ListUtil.isNull(productSpecs)) {
            throw new IllegalArgumentException("请求报文中未包含规格信息");
        }

        JSONObject spec = null;
        List<ProductSpecValuePo> productSpecValuePos = new ArrayList<>();
        boolean hasDefault = false;
        ProductSpecValuePo productSpecValuePo = null;
        for (int specIndex = 0; specIndex < productSpecs.size(); specIndex++) {
            spec = productSpecs.getJSONObject(specIndex);
            productSpecValuePo = BeanConvertUtil.covertBean(spec, ProductSpecValuePo.class);
            productSpecValuePo.setShopId(reqJson.getString("shopId"));
            productSpecValuePos.add(productSpecValuePo);
            if ("T".equals(productSpecValuePo.getIsDefault())) {
                hasDefault = true;
            }
        }

        if (!hasDefault) {
            throw new IllegalArgumentException("请求报文中未包含默认规格");
        }

        ProductPo productPo = BeanConvertUtil.covertBean(reqJson, ProductPo.class);
        productPo.setStoreId(storeId);

        ProductDetailPo productDetailPo = new ProductDetailPo();
        productDetailPo.setStoreId(storeId);
        productDetailPo.setShopId(reqJson.getString("shopId"));
        productDetailPo.setContent(reqJson.getString("content"));

        ShopDistributionModePo shopDistributionModePo = BeanConvertUtil.covertBean(reqJson, ShopDistributionModePo.class);

        ResponseEntity<String> responseEntity = save(productPo,
                coverPhoto,
                carouselFigurePhoto,
                productSpecValuePos,
                productDetailPo,
                userId,
                shopDistributionModePo,
                reqJson);
        cmdDataFlowContext.setResponseEntity(responseEntity);
    }

    public ResponseEntity<String> save(ProductPo productPo,
                                       String coverPhoto,
                                       JSONArray carouselFigurePhoto,
                                       List<ProductSpecValuePo> productSpecValuePos,
                                       ProductDetailPo productDetailPo,
                                       String userId,
                                       ShopDistributionModePo shopDistributionModePo,
                                       JSONObject reqJson) {
        productPo.setProductId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_productId));
        int flag = productInnerServiceSMOImpl.saveProduct(productPo);

        if (flag < 1) {
            return ResultVo.createResponseEntity(ResultVo.CODE_ERROR, "保存失败");
        }
        //关键词处理
        doSavakeywords(productPo);

        //处理手机菜单
        doH5Menu(reqJson, productPo);

        //保存商品封面
        doSavaRentingFile(coverPhoto, productPo, FileRelDto.REL_TYPE_CD_GOODS_COVER);
        for (int carouselIndex = 0; carouselIndex < carouselFigurePhoto.size(); carouselIndex++) {
            doSavaRentingFile(carouselFigurePhoto.getString(carouselIndex), productPo, FileRelDto.REL_TYPE_CD_GOODS_CAROUSEL_FIGURE);
        }
        for (ProductSpecValuePo productSpecValuePo : productSpecValuePos) {
            productSpecValuePo.setStoreId(productPo.getStoreId());
            productSpecValuePo.setProductId(productPo.getProductId());

            productSpecValuePo.setValueId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_valueId));
            productSpecValuePo.setSpecId("-1");
            if (StringUtil.isEmpty(productSpecValuePo.getDeduction())) {
                productSpecValuePo.setDeduction("0.00");
            }
            flag = productSpecValueInnerServiceSMOImpl.saveProductSpecValue(productSpecValuePo);
            if (flag < 1) {
                throw new IllegalArgumentException("保存规格失败");
            }
        }
        productDetailPo.setProductId(productPo.getProductId());
        productDetailPo.setDetailId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailId));
        flag = productDetailInnerServiceSMOImpl.saveProductDetail(productDetailPo);
        if (flag < 1) {
            throw new IllegalArgumentException("保存规格失败");
        }
        InoutOrderPo inoutOrderPo = new InoutOrderPo();
        inoutOrderPo.setOrderId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_orderId));
        inoutOrderPo.setShopId(productPo.getShopId());
        inoutOrderPo.setState(InoutOrderDto.STATE_C);
        inoutOrderPo.setOrderType(InoutOrderDto.ORDER_TYPE_IN);
        inoutOrderPo.setPersonId(userId);
        UserDto userDto = new UserDto();
        userDto.setUserId(userId);
        List<UserDto> userDtos = userInnerServiceSMOImpl.queryUsers(userDto);

        Assert.listOnlyOne(userDtos, "未包含用户信息");
        inoutOrderPo.setPersonName(userDtos.get(0).getName());
        inoutOrderPo.setRemark("添加商品初始化入库");
        //开始保存 inoutOrderProduct
        InoutOrderProductPo inoutOrderProductPo = null;
        List<InoutOrderProductPo> inoutOrderProductPos = new ArrayList<>();

        for (ProductSpecValuePo productSpecValuePo : productSpecValuePos) {
            if (productSpecValuePo.getStock() != null && Integer.parseInt(productSpecValuePo.getStock()) > -1) {//初始库存允许为0
                inoutOrderProductPo = new InoutOrderProductPo();
                inoutOrderProductPo.setRsId("111111");
                inoutOrderProductPo.setSupplierName("添加商品时统一入库");
                inoutOrderProductPo.setPrice(productSpecValuePo.getCostPrice());
                inoutOrderProductPo.setProdCount(productSpecValuePo.getStock());
                BigDecimal price = new BigDecimal(Double.parseDouble(inoutOrderProductPo.getPrice()));
                price = price.multiply(new BigDecimal(Double.parseDouble(inoutOrderProductPo.getProdCount()))).setScale(2, BigDecimal.ROUND_HALF_EVEN);
                inoutOrderProductPo.setAmount(price.doubleValue() + "");
                inoutOrderProductPo.setItemId(GenerateCodeFactory.getGeneratorId("11"));
                inoutOrderProductPo.setOrderId(inoutOrderPo.getOrderId());
                inoutOrderProductPo.setProductId(productPo.getProductId());
                inoutOrderProductPo.setProdName(productPo.getProdName());
                inoutOrderProductPo.setShopId(inoutOrderPo.getShopId());
                inoutOrderProductPo.setState(InoutOrderDto.STATE_W);
                inoutOrderProductPo.setValueId(productSpecValuePo.getValueId());
                inoutOrderProductPo.setRemark("添加商品时统一入库");
                inoutOrderProductPo.setSpecName(productSpecValuePo.getSpecName());
                inoutOrderProductPos.add(inoutOrderProductPo);
            }
        }
        flag = iInoutOrderProductInnerServiceSMOImpl.saveInoutOrderProducts(inoutOrderProductPos);
        if (flag < 1) {
            throw new IllegalArgumentException("提交失败");
        }
        flag = inoutOrderInnerServiceSMOImpl.saveInoutOrder(inoutOrderPo);
        if (flag < 1) {
            throw new IllegalArgumentException("提交失败");
        }
        return ResultVo.createResponseEntity(ResultVo.CODE_OK, "保存成功");
    }

    private void doH5Menu(JSONObject reqJson, ProductPo productPo) {

        if (!reqJson.containsKey("hktIds")) {
            return;
        }

        JSONArray hktIds = reqJson.getJSONArray("hktIds");

        if (hktIds == null || hktIds.size() < 1) {
            return;
        }
        String hktId = "";
        HousekeepingTypeDto housekeepingTypeDto = null;
        List<HousekeepingTypeDto> housekeepingTypeDtos = null;
        ProductH5MenuPo productH5MenuPo = null;
        for (int hktIndex = 0; hktIndex < hktIds.size(); hktIndex++) {
            hktId = hktIds.getString(hktIndex);
            housekeepingTypeDto = new HousekeepingTypeDto();
            housekeepingTypeDto.setHktId(hktId);
            housekeepingTypeDtos = housekeepingTypeInnerServiceSMOImpl.queryHousekeepingTypes(housekeepingTypeDto);

            if (housekeepingTypeDtos == null || housekeepingTypeDtos.size() < 1) {
                continue;
            }

            productH5MenuPo = new ProductH5MenuPo();
            productH5MenuPo.setHktId(hktId);
            productH5MenuPo.setHktName(housekeepingTypeDtos.get(0).getHktName());
            productH5MenuPo.setProductId(productPo.getProductId());
            productH5MenuPo.setShopId(productPo.getShopId());
            productH5MenuPo.setStoreId(productPo.getStoreId());
            productH5MenuPo.setPhmId(GenerateCodeFactory.getGeneratorId("11"));
            int flag = productH5MenuV1InnerServiceSMOImpl.saveProductH5Menu(productH5MenuPo);

            if (flag < 1) {
                throw new CmdException("保存数据失败");
            }
        }
    }

    /**
     * 保存关键词
     *
     * @param productPo
     */
    private void doSavakeywords(ProductPo productPo) {
        String[] keywor = productPo.getKeyword().replaceAll("；", ";").split(";");
        for (String keyword : keywor) {
            ProductServKeywordPo servKeywordPo = new ProductServKeywordPo();
            servKeywordPo.setKeywordId(GenerateCodeFactory.getGeneratorId("11"));
            servKeywordPo.setKeywordName(keyword.trim());
            servKeywordPo.setKeywordType(HousekeepingServDto.KEYWORD_PROD_TYPE_CD);
            servKeywordPo.setObjId(productPo.getProductId());
            servKeywordPo.setShopId(productPo.getShopId());
            int save = productServKeywordInnerServiceSMOImpl.saveProductServKeyword(servKeywordPo);
            if (save < 1) {
                throw new IllegalArgumentException("商品关键字保存失败");
            }
        }
    }

    /**
     * 保存房屋租赁 图片
     *
     * @param fileName
     * @param productPo
     */
    private void doSavaRentingFile(String fileName, ProductPo productPo, String fileTypeCd) {

        FileRelPo fileRelPo = new FileRelPo();
        fileRelPo.setObjId(productPo.getProductId());
        fileRelPo.setRelTypeCd(fileTypeCd);
        fileRelPo.setFileRelId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_relId));
        fileRelPo.setFileRealName(fileName);
        fileRelPo.setFileSaveName(fileName);
        fileRelPo.setSaveWay(FileRelDto.SAVE_WAY_FTP);
        int save = fileRelInnerServiceSMOImpl.saveFileRel(fileRelPo);

        if (save < 1) {
            throw new IllegalArgumentException("保存文件失败");
        }
    }
}
